package com.education.ai.service.impl;

import com.education.ai.dao.StudentMistakeCollectionDao;
import com.education.ai.dao.StudentPracticeSessionDao;
import com.education.ai.dao.ExerciseDao;
import com.education.ai.entity.Exercise;
import com.education.ai.entity.StudentMistakeCollection;
import com.education.ai.entity.StudentPracticeSession;
import com.education.ai.service.AiTeachingService;
import com.education.ai.service.StudentPracticeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Collections;
import java.sql.Timestamp;
import java.util.Comparator;

import com.education.ai.util.JdbcUtil;

/**
 * 学生练习服务实现类
 */
@Service
public class StudentPracticeServiceImpl implements StudentPracticeService {
    
    private static final Logger log = LoggerFactory.getLogger(StudentPracticeServiceImpl.class);
    
    @Autowired
    private JdbcUtil jdbcUtil;
    
    @Autowired(required = false)
    private StudentPracticeSessionDao practiceSessionDao;
    
    @Autowired(required = false)
    private StudentMistakeCollectionDao mistakeCollectionDao;
    
    @Autowired(required = false)
    private ExerciseDao exerciseDao;
    
    @Autowired
    private AiTeachingService aiTeachingService;
    
    @Override
    @Transactional
    public Map<String, Object> savePracticeSession(StudentPracticeSession session, List<Map<String, Object>> answers) {
        log.info("保存学生练习会话 - 学生ID: {}, 学科: {}", session.getStudentId(), session.getSubject());
        
        // 添加调试日志，检查所有字段值
        log.debug("练习会话字段值检查: studentId={}, subject={}, knowledgePoint={}, difficulty={}, practiceType={}, totalCount={}, correctCount={}, completionTime={}, startTime={}, endTime={}",
            session.getStudentId(),
            session.getSubject(),
            session.getKnowledgePoint(),
            session.getDifficulty(),
            session.getPracticeType(),
            session.getTotalCount(),
            session.getCorrectCount(),
            session.getCompletionTime(),
            session.getStartTime(),
            session.getEndTime());
        
        // 确保必要字段不为空
        if (session.getDifficulty() == null) {
            log.debug("difficulty为空，设置默认值");
            session.setDifficulty("中等");
        }
        
        if (session.getPracticeType() == null) {
            log.debug("practiceType为空，设置默认值");
            session.setPracticeType("日常练习");
        }
        
        // 设置会话结束时间
        if (session.getEndTime() == null) {
            session.setEndTime(LocalDateTime.now());
        }
        
        // 设置开始时间（如果未设置）
        if (session.getStartTime() == null) {
            // 根据完成时间推算开始时间
            session.setStartTime(session.getEndTime().minusSeconds(session.getCompletionTime() != null ? session.getCompletionTime() : 0));
        }
        
        // 计算准确率
        if (session.getCorrectCount() != null && session.getTotalCount() != null && session.getTotalCount() > 0) {
            double accuracy = (double) session.getCorrectCount() / session.getTotalCount();
            session.setAccuracy(accuracy);
        }
        
        // 保存会话记录
        StudentPracticeSession savedSession;
        try {
            // 检查DAO是否正确注入
            if (practiceSessionDao == null) {
                log.error("practiceSessionDao未注入");
                Map<String, Object> result = new HashMap<>();
                result.put("success", false);
                result.put("message", "保存练习会话失败: practiceSessionDao未注入");
                return result;
            }
            
            savedSession = practiceSessionDao.save(session);
            log.info("练习会话已保存，ID: {}", savedSession.getId());
        } catch (Exception e) {
            log.error("保存练习会话失败: {}", e.getMessage(), e);
            
            // 如果DAO未注入或其他原因导致保存失败，返回错误信息
            Map<String, Object> result = new HashMap<>();
            result.put("success", false);
            result.put("message", "保存练习会话失败: " + e.getMessage());
            return result;
        }
        
        // 处理练习答案，保存错题
        List<StudentMistakeCollection> mistakes = processAnswers(session.getStudentId(), answers);
        
        // 更新学生学习进度数据
        updateLearningProgress(session);
        
        // 生成分析结果
        Map<String, Object> result = new HashMap<>();
        result.put("sessionId", savedSession.getId());
        result.put("correctCount", session.getCorrectCount());
        result.put("totalCount", session.getTotalCount());
        result.put("accuracy", session.getAccuracy());
        result.put("completionTime", session.getCompletionTime());
        
        // 计算得分（基于准确率和完成时间）
        int score = calculateScore(session);
        result.put("score", score);
        
        // 获取AI分析建议
        String analysis = "";
        try {
            analysis = aiTeachingService.analyzeStudentPracticeSession(session);
            log.info("已获取AI分析建议");
        } catch (Exception e) {
            log.warn("获取AI分析建议失败: {}", e.getMessage());
            // 生成基本的分析文本
            analysis = generateBasicAnalysis(session, mistakes);
        }
        result.put("analysis", analysis);
        
        // 获取知识点掌握情况
        Map<String, Object> knowledgePointsMastery = getKnowledgePointsMastery(session.getStudentId(), session.getSubject());
        result.put("knowledgePoints", knowledgePointsMastery);
        
        // 返回错题集信息
        result.put("mistakesCount", mistakes.size());
        
        // 生成习题详情
        List<Map<String, Object>> questionDetails = generateQuestionDetails(answers);
        result.put("questions", questionDetails);
        
        result.put("success", true);
        return result;
    }
    
    @Override
    public List<StudentMistakeCollection> getMistakeCollection(String studentId, String subject) {
        log.info("获取学生错题集 - 学生ID: {}, 学科: {}", studentId, subject);
        
        try {
            if (subject != null && !subject.isEmpty()) {
                return mistakeCollectionDao.findByStudentIdAndSubject(studentId, subject);
            } else {
                return mistakeCollectionDao.findByStudentId(studentId);
            }
        } catch (Exception e) {
            log.error("获取错题集失败: {}", e.getMessage(), e);
            
            // 如果DAO未注入或其他原因导致查询失败，返回空列表
            // 实际项目中应该抛出异常
            return new ArrayList<>();
        }
    }
    
    @Override
    @Transactional
    public StudentMistakeCollection addToMistakeCollection(StudentMistakeCollection mistake) {
        log.info("添加错题 - 学生ID: {}, 题目ID: {}", mistake.getStudentId(), mistake.getExerciseId());
        
        try {
            // 检查是否已存在该错题
            List<StudentMistakeCollection> existingMistakes = 
                    mistakeCollectionDao.findByStudentIdAndExerciseId(mistake.getStudentId(), mistake.getExerciseId());
            
            if (!existingMistakes.isEmpty()) {
                // 已存在该错题，更新错误次数和最后错误时间
                StudentMistakeCollection existingMistake = existingMistakes.get(0);
                existingMistake.setMistakeCount(existingMistake.getMistakeCount() + 1);
                existingMistake.setLastMistakeTime(LocalDateTime.now());
                existingMistake.setStudentAnswer(mistake.getStudentAnswer());
                return mistakeCollectionDao.save(existingMistake);
            } else {
                // 不存在，保存新错题
                if (mistake.getCreateTime() == null) {
                    mistake.setCreateTime(LocalDateTime.now());
                }
                if (mistake.getLastMistakeTime() == null) {
                    mistake.setLastMistakeTime(LocalDateTime.now());
                }
                if (mistake.getMistakeCount() == null) {
                    mistake.setMistakeCount(1);
                }
                return mistakeCollectionDao.save(mistake);
            }
        } catch (Exception e) {
            log.error("添加错题失败: {}", e.getMessage(), e);
            throw new RuntimeException("添加错题失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional
    public void removeFromMistakeCollection(Long mistakeId) {
        log.info("从错题集中移除 - ID: {}", mistakeId);
        
        try {
            mistakeCollectionDao.deleteById(mistakeId);
        } catch (Exception e) {
            log.error("移除错题失败: {}", e.getMessage(), e);
            throw new RuntimeException("移除错题失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public List<StudentPracticeSession> getRecentPracticeSessions(String studentId, int limit) {
        log.info("获取学生最近练习会话 - 学生ID: {}, 限制: {}", studentId, limit);
        
        try {
            return practiceSessionDao.findRecentByStudentId(studentId, limit);
        } catch (Exception e) {
            log.error("获取最近练习会话失败: {}", e.getMessage(), e);
            // 如果DAO未注入或其他原因导致查询失败，返回空列表
            return new ArrayList<>();
        }
    }
    
    @Override
    public Map<String, Object> generateLearningReport(String studentId, String subject) {
        log.info("生成学习报告 - 学生ID: {}, 学科: {}", studentId, subject);
        
        Map<String, Object> report = new HashMap<>();
        
        try {
            // 1. 获取学生练习会话数据
            List<StudentPracticeSession> sessions = 
                    practiceSessionDao.findByStudentIdAndSubject(studentId, subject);
            
            // 2. 统计数据
            int totalSessions = sessions.size();
            int totalExercises = 0;
            int totalCorrect = 0;
            int totalTime = 0; // 总时间(秒)
            
            for (StudentPracticeSession session : sessions) {
                totalExercises += session.getTotalCount() != null ? session.getTotalCount() : 0;
                totalCorrect += session.getCorrectCount() != null ? session.getCorrectCount() : 0;
                totalTime += session.getCompletionTime() != null ? session.getCompletionTime() : 0;
            }
            
            double averageAccuracy = totalExercises > 0 ? (double) totalCorrect / totalExercises : 0;
            
            // 3. 错题分析
            List<StudentMistakeCollection> mistakes = 
                    mistakeCollectionDao.findByStudentIdAndSubject(studentId, subject);
            
            // 4. 构建报告
            report.put("studentId", studentId);
            report.put("subject", subject);
            report.put("totalSessions", totalSessions);
            report.put("totalExercises", totalExercises);
            report.put("totalCorrect", totalCorrect);
            report.put("totalWrong", totalExercises - totalCorrect);
            report.put("averageAccuracy", averageAccuracy);
            report.put("totalTime", totalTime);
            report.put("mistakesCount", mistakes.size());
            
            // 5. AI分析建议(实际项目中通过AI服务生成)
            String analysis = "基于您的学习数据分析...";
            try {
                analysis = aiTeachingService.generateLearningReport(studentId, subject);
            } catch (Exception e) {
                log.warn("获取AI分析建议失败: {}", e.getMessage());
            }
            report.put("aiAnalysis", analysis);
            
        } catch (Exception e) {
            log.error("生成学习报告失败: {}", e.getMessage(), e);
            report.put("error", "生成报告失败: " + e.getMessage());
        }
        
        return report;
    }
    
    // 处理练习答案，保存错题
    private List<StudentMistakeCollection> processAnswers(String studentId, List<Map<String, Object>> answers) {
        List<StudentMistakeCollection> mistakes = new ArrayList<>();
        
        if (answers == null || answers.isEmpty()) {
            log.info("没有提供答案数据，跳过错题处理");
            return mistakes;
        }
        
        log.info("处理{}道题目答案", answers.size());
        
        Map<String, Integer> knowledgePointMistakes = new HashMap<>();
        Map<String, Integer> questionTypeMistakes = new HashMap<>();
        
        for (Map<String, Object> answerData : answers) {
            try {
                // 获取题目ID
                Long exerciseId = Long.valueOf(answerData.get("exerciseId").toString());
                String userAnswer = answerData.get("userAnswer") != null ? answerData.get("userAnswer").toString() : "";
                boolean isCorrect = Boolean.parseBoolean(answerData.get("isCorrect").toString());
                
                // 如果答错了，添加到错题集
                if (!isCorrect) {
                    // 获取题目信息
                    Optional<Exercise> exerciseOpt = exerciseDao.findById(exerciseId);
                    if (exerciseOpt.isPresent()) {
                        Exercise exercise = exerciseOpt.get();
                        
                        // 统计知识点和题型错误
                        String knowledgePoint = exercise.getTopic();
                        String questionType = exercise.getQuestionType();
                        
                        // 更新知识点错误统计
                        if (knowledgePoint != null && !knowledgePoint.isEmpty()) {
                            knowledgePointMistakes.put(knowledgePoint, 
                                knowledgePointMistakes.getOrDefault(knowledgePoint, 0) + 1);
                        }
                        
                        // 更新题型错误统计
                        if (questionType != null && !questionType.isEmpty()) {
                            questionTypeMistakes.put(questionType, 
                                questionTypeMistakes.getOrDefault(questionType, 0) + 1);
                        }
                        
                        // 生成错误分析
                        String errorAnalysis = generateErrorAnalysis(exercise, userAnswer);
                        
                        // 创建错题记录
                        StudentMistakeCollection mistake = StudentMistakeCollection.builder()
                                .studentId(studentId)
                                .exerciseId(exerciseId)
                                .subject(exercise.getSubject())
                                .knowledgePoint(exercise.getTopic())
                                .questionType(exercise.getQuestionType())
                                .content(exercise.getContent())
                                .studentAnswer(userAnswer)
                                .correctAnswer(exercise.getAnswer())
                                .analysis(errorAnalysis)
                                .mistakeCount(1)
                                .lastMistakeTime(LocalDateTime.now())
                                .createTime(LocalDateTime.now())
                                .build();
                        
                        // 保存错题
                        StudentMistakeCollection saved = addToMistakeCollection(mistake);
                        mistakes.add(saved);
                        
                        // 保存到练习详情表
                        saveExerciseDetail(studentId, exercise, userAnswer, isCorrect);
                    }
                } else {
                    // 即使回答正确，也保存到练习详情表
                    Optional<Exercise> exerciseOpt = exerciseDao.findById(exerciseId);
                    if (exerciseOpt.isPresent()) {
                        saveExerciseDetail(studentId, exerciseOpt.get(), userAnswer, true);
                    }
                }
            } catch (Exception e) {
                log.error("处理答案数据失败: {}", e.getMessage(), e);
            }
        }
        
        // 记录学生知识点弱点
        if (!knowledgePointMistakes.isEmpty()) {
            String weakestPoint = Collections.max(knowledgePointMistakes.entrySet(), 
                    Map.Entry.comparingByValue()).getKey();
            log.info("学生[{}]的最弱知识点: {}, 错误次数: {}", 
                    studentId, weakestPoint, knowledgePointMistakes.get(weakestPoint));
            
            // 保存到学生分析表
            saveStudentAnalysis(studentId, weakestPoint, knowledgePointMistakes.get(weakestPoint));
        }
        
        log.info("共添加{}道错题", mistakes.size());
        return mistakes;
    }
    
    // 生成错误分析
    private String generateErrorAnalysis(Exercise exercise, String userAnswer) {
        // 如果题目本身有解析，优先使用题目的解析
        if (exercise.getAnalysis() != null && !exercise.getAnalysis().isEmpty()) {
            return exercise.getAnalysis();
        }
        
        StringBuilder analysis = new StringBuilder();
        analysis.append("题目解析：\n");
        
        // 根据题型生成基本解析
        String questionType = exercise.getQuestionType();
        if (questionType != null) {
            if (questionType.contains("选择题")) {
                analysis.append("本题为选择题，正确答案是 ").append(exercise.getAnswer()).append("。\n");
                if (userAnswer != null && !userAnswer.isEmpty()) {
                    analysis.append("你的答案是 ").append(userAnswer).append("。\n");
                }
            } else if (questionType.contains("填空题")) {
                analysis.append("本题为填空题，正确答案是 ").append(exercise.getAnswer()).append("。\n");
            } else if (questionType.contains("计算题")) {
                analysis.append("本题为计算题，请注意计算过程和结果的准确性。\n");
                analysis.append("正确答案是 ").append(exercise.getAnswer()).append("。\n");
            } else {
                analysis.append("正确答案是 ").append(exercise.getAnswer()).append("。\n");
            }
        } else {
            analysis.append("正确答案是 ").append(exercise.getAnswer()).append("。\n");
        }
        
        // 添加知识点信息
        if (exercise.getTopic() != null && !exercise.getTopic().isEmpty()) {
            analysis.append("本题考查的知识点是【").append(exercise.getTopic()).append("】。\n");
        }
        
        return analysis.toString();
    }
    
    // 保存到练习详情表
    private void saveExerciseDetail(String studentId, Exercise exercise, String userAnswer, boolean isCorrect) {
        try {
            // 查询最新的practice_id
            String sessionSql = "SELECT id FROM student_practice_sessions WHERE student_id = ? ORDER BY id DESC LIMIT 1";
            List<Map<String, Object>> sessionResults = jdbcUtil.executeQuery(sessionSql, studentId);
            
            Long practiceId = 0L;
            if (!sessionResults.isEmpty()) {
                practiceId = ((Number) sessionResults.get(0).get("id")).longValue();
            }
            
            // 修改SQL，确保包含题目内容和正确答案
            String sql = "INSERT INTO student_practice_details " +
                    "(practice_id, exercise_id, question, student_answer, correct_answer, is_correct) " +
                    "VALUES (?, ?, ?, ?, ?, ?)";
            
            jdbcUtil.executeUpdate(sql, 
                    practiceId, // 使用查询到的practice_id
                    exercise.getId(),
                    exercise.getContent(), // 使用正确的字段名
                    userAnswer, 
                    exercise.getAnswer(), // 添加正确答案
                    isCorrect ? 1 : 0);
            
            log.debug("已保存学生[{}]练习题[{}]详情", studentId, exercise.getId());
        } catch (Exception e) {
            log.error("保存练习详情失败: {}", e.getMessage(), e);
        }
    }
    
    // 保存学生分析数据
    private void saveStudentAnalysis(String studentId, String weakKnowledgePoint, int mistakeCount) {
        try {
            // 先执行sql/fix_student_practice_tables.sql来确保表结构正确
            
            // 检查是否已存在分析记录
            String checkSql = "SELECT id FROM student_analysis WHERE student_id = ? AND topic = ?";
            List<Map<String, Object>> existing = jdbcUtil.executeQuery(checkSql, studentId, weakKnowledgePoint);
            
            if (existing.isEmpty()) {
                // 插入新记录
                String insertSql = "INSERT INTO student_analysis " +
                        "(student_id, topic, mistake_count, analysis_time) " +
                        "VALUES (?, ?, ?, ?)";
                
                jdbcUtil.executeUpdate(insertSql, 
                        studentId, 
                        weakKnowledgePoint, 
                        mistakeCount, 
                        Timestamp.valueOf(LocalDateTime.now()));
            } else {
                // 更新现有记录
                String updateSql = "UPDATE student_analysis " +
                        "SET mistake_count = mistake_count + ?, analysis_time = ? " +
                        "WHERE student_id = ? AND topic = ?";
                
                jdbcUtil.executeUpdate(updateSql, 
                        mistakeCount, 
                        Timestamp.valueOf(LocalDateTime.now()), 
                        studentId, 
                        weakKnowledgePoint);
            }
            
            log.info("已更新学生[{}]的知识点[{}]分析数据", studentId, weakKnowledgePoint);
        } catch (Exception e) {
            log.error("保存学生分析数据失败: {}", e.getMessage(), e);
        }
    }
    
    @Override
    @Transactional
    public void updateMistakeStatus(Long mistakeId, String studentId, boolean resolved) {
        log.info("更新错题状态 - ID: {}, 学生ID: {}, 解决状态: {}", mistakeId, studentId, resolved);
        
        try {
            // 1. 获取错题信息
            StudentMistakeCollection mistake = mistakeCollectionDao.findById(mistakeId);
            if (mistake == null) {
                throw new RuntimeException("错题不存在");
            }
            
            // 2. 验证学生ID
            if (!mistake.getStudentId().equals(studentId)) {
                throw new RuntimeException("无权限更新此错题状态");
            }
            
            // 3. 更新student_practice_details表中的is_correct字段
            String sql = "UPDATE student_practice_details SET is_correct = ? " +
                        "WHERE exercise_id = ? AND student_answer IS NOT NULL";
            int updated = jdbcUtil.executeUpdate(sql, 
                    resolved ? 1 : 0,  // 如果已解决，设置is_correct为1，否则为0
                    mistake.getExerciseId());
            
            // 4. 更新错题集中的错误次数（如果已解决，设置为0，否则设为至少1）
            if (resolved) {
                mistake.setMistakeCount(0);
            } else {
                // 如果未解决，设置为至少1次
                mistake.setMistakeCount(Math.max(1, mistake.getMistakeCount()));
            }
            mistakeCollectionDao.save(mistake);
            
            log.info("成功更新错题状态，影响行数: {}", updated);
        } catch (Exception e) {
            log.error("更新错题状态失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新错题状态失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public boolean validateMistakeOwnership(Long mistakeId, String studentId) {
        log.info("验证错题所属权 - 错题ID: {}, 学生ID: {}", mistakeId, studentId);
        
        try {
            StudentMistakeCollection mistake = mistakeCollectionDao.findById(mistakeId);
            
            if (mistake == null) {
                log.warn("错题不存在: {}", mistakeId);
                return false;
            }
            
            boolean isOwner = mistake.getStudentId().equals(studentId);
            log.info("错题所属验证结果: {}", isOwner);
            
            return isOwner;
        } catch (Exception e) {
            log.error("验证错题所属权失败: {}", e.getMessage(), e);
            return false;
        }
    }
    
    // 计算练习得分
    private int calculateScore(StudentPracticeSession session) {
        // 基础分数（基于准确率）
        double accuracyScore = 0;
        if (session.getAccuracy() != null) {
            accuracyScore = session.getAccuracy() * 100;
        } else if (session.getCorrectCount() != null && session.getTotalCount() != null && session.getTotalCount() > 0) {
            accuracyScore = (double) session.getCorrectCount() / session.getTotalCount() * 100;
        }
        
        // 时间因子（完成越快，得分越高，但有下限）
        double timeFactor = 1.0;
        if (session.getCompletionTime() != null && session.getTotalCount() != null && session.getTotalCount() > 0) {
            // 每题平均时间（秒）
            double avgTimePerQuestion = (double) session.getCompletionTime() / session.getTotalCount();
            
            // 根据平均时间调整因子（30秒为标准时间）
            if (avgTimePerQuestion < 30) {
                // 比标准快，提高分数
                timeFactor = 1.0 + (30 - avgTimePerQuestion) / 60;  // 最多提高50%
            } else if (avgTimePerQuestion > 60) {
                // 比标准慢太多，降低分数
                timeFactor = Math.max(0.8, 1.0 - (avgTimePerQuestion - 60) / 300);  // 最多降低20%
            }
        }
        
        // 计算最终得分
        int finalScore = (int) Math.round(accuracyScore * timeFactor);
        
        // 确保得分在0-100范围内
        return Math.max(0, Math.min(100, finalScore));
    }
    
    // 生成基本分析文本（当AI服务不可用时）
    private String generateBasicAnalysis(StudentPracticeSession session, List<StudentMistakeCollection> mistakes) {
        StringBuilder analysis = new StringBuilder();
        
        // 1. 练习概况
        analysis.append("练习概况：\n");
        
        if (session.getAccuracy() != null) {
            double accuracyPercent = session.getAccuracy() * 100;
            analysis.append(String.format("您完成了%d道题目，正确率为%.1f%%。\n", 
                    session.getTotalCount(), accuracyPercent));
            
            // 根据正确率评价
            if (accuracyPercent >= 90) {
                analysis.append("表现优秀！继续保持。\n");
            } else if (accuracyPercent >= 70) {
                analysis.append("表现良好，还有提升空间。\n");
            } else if (accuracyPercent >= 50) {
                analysis.append("表现一般，需要加强练习。\n");
            } else {
                analysis.append("需要更多练习来巩固知识点。\n");
            }
        }
        
        // 2. 错题分析
        if (!mistakes.isEmpty()) {
            analysis.append("\n错题分析：\n");
            analysis.append(String.format("本次练习有%d道错题，建议重点关注以下知识点：\n", mistakes.size()));
            
            // 统计错题知识点
            Map<String, Integer> knowledgePointCounts = new HashMap<>();
            for (StudentMistakeCollection mistake : mistakes) {
                String knowledgePoint = mistake.getKnowledgePoint();
                if (knowledgePoint != null && !knowledgePoint.isEmpty()) {
                    knowledgePointCounts.put(knowledgePoint, 
                            knowledgePointCounts.getOrDefault(knowledgePoint, 0) + 1);
                }
            }
            
            // 列出前3个最常见的知识点
            knowledgePointCounts.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .limit(3)
                    .forEach(entry -> {
                        analysis.append(String.format("- %s（%d题）\n", 
                                entry.getKey(), entry.getValue()));
                    });
        }
        
        // 3. 时间分析
        if (session.getCompletionTime() != null && session.getTotalCount() != null && session.getTotalCount() > 0) {
            double avgTimePerQuestion = (double) session.getCompletionTime() / session.getTotalCount();
            analysis.append(String.format("\n时间分析：\n平均每题用时%.1f秒。", avgTimePerQuestion));
            
            if (avgTimePerQuestion < 20) {
                analysis.append("解题速度很快，但请确保理解题目和解题过程。\n");
            } else if (avgTimePerQuestion > 60) {
                analysis.append("解题速度较慢，可以通过更多练习来提高解题速度。\n");
            } else {
                analysis.append("解题速度适中。\n");
            }
        }
        
        // 4. 建议
        analysis.append("\n建议：\n");
        if (!mistakes.isEmpty()) {
            analysis.append("- 复习错题本中的题目，巩固薄弱知识点\n");
            analysis.append("- 针对性练习出错较多的知识点\n");
        } else {
            analysis.append("- 尝试更高难度的习题来挑战自己\n");
        }
        analysis.append("- 定期复习，保持知识点的连贯性\n");
        
        return analysis.toString();
    }
    
    // 更新学生学习进度数据
    private void updateLearningProgress(StudentPracticeSession session) {
        try {
            // 将中文学科名称转换为英文代码
            String subjectCode = convertSubjectToCode(session.getSubject());
            
            // 查询学生现有进度数据
            String checkSql = "SELECT * FROM student_learning_progress " +
                    "WHERE student_id = ? AND subject = ?";
            List<Map<String, Object>> existingProgress = jdbcUtil.executeQuery(
                    checkSql, session.getStudentId(), subjectCode);
            
            if (existingProgress.isEmpty()) {
                // 没有现有记录，创建新记录
                String insertSql = "INSERT INTO student_learning_progress " +
                        "(student_id, subject, total_exercises, correct_exercises, " +
                        "total_time, last_practice_time, mastery_level) " +
                        "VALUES (?, ?, ?, ?, ?, ?, ?)";
                
                double masteryLevel = calculateMasteryLevel(
                        session.getCorrectCount(), session.getTotalCount(), 0, 0);
                
                jdbcUtil.executeUpdate(insertSql,
                        session.getStudentId(),
                        subjectCode,
                        session.getTotalCount(),
                        session.getCorrectCount(),
                        session.getCompletionTime(),
                        Timestamp.valueOf(session.getEndTime()),
                        masteryLevel);
            } else {
                // 更新现有记录
                Map<String, Object> progress = existingProgress.get(0);
                
                int currentTotalExercises = getIntValue(progress, "total_exercises");
                int currentCorrectExercises = getIntValue(progress, "correct_exercises");
                int currentTotalTime = getIntValue(progress, "total_time");
                
                // 计算新的掌握程度
                double masteryLevel = calculateMasteryLevel(
                        session.getCorrectCount(), session.getTotalCount(),
                        currentCorrectExercises, currentTotalExercises);
                
                String updateSql = "UPDATE student_learning_progress SET " +
                        "total_exercises = total_exercises + ?, " +
                        "correct_exercises = correct_exercises + ?, " +
                        "total_time = total_time + ?, " +
                        "last_practice_time = ?, " +
                        "mastery_level = ? " +
                        "WHERE student_id = ? AND subject = ?";
                
                jdbcUtil.executeUpdate(updateSql,
                        session.getTotalCount(),
                        session.getCorrectCount(),
                        session.getCompletionTime(),
                        Timestamp.valueOf(session.getEndTime()),
                        masteryLevel,
                        session.getStudentId(),
                        subjectCode);
            }
            
            log.info("已更新学生[{}]在[{}]学科的学习进度，存储代码为：{}", 
                    session.getStudentId(), session.getSubject(), subjectCode);
        } catch (Exception e) {
            log.error("更新学习进度失败: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 将中文学科名称转换为英文代码
     */
    private String convertSubjectToCode(String subjectName) {
        if (subjectName == null) return "";
        
        switch (subjectName) {
            case "语文": return "chinese";
            case "数学": return "math";
            case "英语": return "english";
            case "物理": return "physics";
            case "化学": return "chemistry";
            case "生物": return "biology";
            case "政治": return "politics";
            case "历史": return "history";
            case "地理": return "geography";
            default: 
                // 如果已经是英文代码，则直接返回
                if (isEnglishSubjectCode(subjectName)) {
                    return subjectName.toLowerCase();
                }
                // 否则返回原值，日志记录无法识别的学科
                log.warn("无法识别的学科名称: {}", subjectName);
                return subjectName;
        }
    }
    
    /**
     * 判断是否已经是英文学科代码
     */
    private boolean isEnglishSubjectCode(String subject) {
        if (subject == null) return false;
        String lowerSubject = subject.toLowerCase();
        return lowerSubject.equals("chinese") || lowerSubject.equals("math") || 
               lowerSubject.equals("english") || lowerSubject.equals("physics") || 
               lowerSubject.equals("chemistry") || lowerSubject.equals("biology") || 
               lowerSubject.equals("politics") || lowerSubject.equals("history") || 
               lowerSubject.equals("geography");
    }
    
    // 从Map中安全获取整数值
    private int getIntValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return 0;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            return 0;
        }
    }
    
    // 计算学科掌握程度
    private double calculateMasteryLevel(int newCorrect, int newTotal, int oldCorrect, int oldTotal) {
        int totalExercises = oldTotal + newTotal;
        if (totalExercises == 0) {
            return 0.0;
        }
        
        int totalCorrect = oldCorrect + newCorrect;
        double baseAccuracy = (double) totalCorrect / totalExercises;
        
        // 题目数量因子（做题越多，掌握度越高）
        double quantityFactor = Math.min(1.0, totalExercises / 100.0);
        
        // 计算最终掌握度（0-1之间）
        double masteryLevel = baseAccuracy * (0.7 + 0.3 * quantityFactor);
        
        return Math.min(1.0, masteryLevel);
    }
    
    // 生成习题详情
    private List<Map<String, Object>> generateQuestionDetails(List<Map<String, Object>> answers) {
        List<Map<String, Object>> details = new ArrayList<>();
        
        if (answers == null || answers.isEmpty()) {
            return details;
        }
        
        for (Map<String, Object> answer : answers) {
            try {
                Long exerciseId = Long.valueOf(answer.get("exerciseId").toString());
                Optional<Exercise> exerciseOpt = exerciseDao.findById(exerciseId);
                
                if (exerciseOpt.isPresent()) {
                    Exercise exercise = exerciseOpt.get();
                    
                    Map<String, Object> detail = new HashMap<>();
                    detail.put("id", exercise.getId());
                    detail.put("content", exercise.getContent());
                    detail.put("type", exercise.getQuestionType());
                    detail.put("userAnswer", answer.get("userAnswer"));
                    detail.put("correctAnswer", exercise.getAnswer());
                    detail.put("isCorrect", answer.get("isCorrect"));
                    detail.put("explanation", exercise.getAnalysis());
                    
                    details.add(detail);
                }
            } catch (Exception e) {
                log.error("生成习题详情失败: {}", e.getMessage(), e);
            }
        }
        
        return details;
    }
    
    // 获取知识点掌握情况
    private Map<String, Object> getKnowledgePointsMastery(String studentId, String subject) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> knowledgePoints = new ArrayList<>();
        
        try {
            // 查询该学科下的知识点错题统计
            String mistakesSql = "SELECT topic, COUNT(*) as mistake_count " +
                    "FROM student_mistake_collection " +
                    "WHERE student_id = ? AND subject = ? " +
                    "GROUP BY topic";
            
            List<Map<String, Object>> mistakesData = jdbcUtil.executeQuery(
                    mistakesSql, studentId, subject);
            
            // 查询该学科下的知识点练习总数（尝试不同的方式获取练习数据）
            List<Map<String, Object>> practiceData = new ArrayList<>();
            
            try {
                // 尝试通过student_practice_sessions表获取练习数据
                String practiceSql = "SELECT topic, SUM(total_count) as total_count " +
                        "FROM student_practice_sessions " +
                        "WHERE student_id = ? AND subject = ? " +
                        "GROUP BY topic";
                
                practiceData = jdbcUtil.executeQuery(practiceSql, studentId, subject);
            } catch (Exception e) {
                log.error("通过student_practice_sessions获取练习数据失败: {}", e.getMessage());
                
                // 如果上述查询失败，尝试通过exercises表获取
                try {
                    String exerciseSql = "SELECT topic, COUNT(*) as total_count " +
                            "FROM exercises " +
                            "WHERE subject = ? " +
                            "GROUP BY topic";
                    
                    practiceData = jdbcUtil.executeQuery(exerciseSql, subject);
                } catch (Exception ex) {
                    log.error("通过exercises表获取练习数据失败: {}", ex.getMessage());
                }
            }
            
            // 转换为Map方便查找
            Map<String, Integer> mistakeCountMap = new HashMap<>();
            for (Map<String, Object> data : mistakesData) {
                String knowledgePoint = (String) data.get("topic");
                if (knowledgePoint != null && !knowledgePoint.isEmpty()) {
                    mistakeCountMap.put(knowledgePoint, ((Number) data.get("mistake_count")).intValue());
                }
            }
            
            // 计算每个知识点的掌握度
            for (Map<String, Object> data : practiceData) {
                String knowledgePoint = (String) data.get("topic");
                if (knowledgePoint != null && !knowledgePoint.isEmpty()) {
                    int totalCount = ((Number) data.get("total_count")).intValue();
                    int mistakeCount = mistakeCountMap.getOrDefault(knowledgePoint, 0);
                    
                    double masteryLevel = 1.0;
                    if (totalCount > 0) {
                        masteryLevel = Math.max(0, 1.0 - (double) mistakeCount / totalCount);
                    }
                    
                    Map<String, Object> pointData = new HashMap<>();
                    pointData.put("name", knowledgePoint);
                    pointData.put("mastery", Math.round(masteryLevel * 100));
                    pointData.put("totalCount", totalCount);
                    pointData.put("mistakeCount", mistakeCount);
                    
                    knowledgePoints.add(pointData);
                }
            }
            
            // 按掌握度排序（从低到高）
            knowledgePoints.sort(Comparator.comparingDouble(p -> ((Number) p.get("mastery")).doubleValue()));
        } catch (Exception e) {
            log.error("获取知识点掌握情况失败: {}", e.getMessage(), e);
        }
        
        result.put("knowledgePoints", knowledgePoints);
        result.put("totalPoints", knowledgePoints.size());
        
        return result;
    }

    @Override
    public void updateLearningProgress(String studentId, String subject, String knowledgePoint, Boolean isCorrect) {
        log.info("更新学习进度 - 学生ID: {}, 学科: {}, 知识点: {}, 是否正确: {}", 
                studentId, subject, knowledgePoint, isCorrect);
        
        try {
            // 查询或创建学生学习进度记录
            String sql = "SELECT * FROM student_learning_progress WHERE student_id = ? AND subject = ?";
            List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, studentId, subject);
            
            if (results.isEmpty()) {
                // 创建新记录
                sql = "INSERT INTO student_learning_progress (student_id, subject, total_exercises, correct_exercises, total_time, last_practice_time) " +
                      "VALUES (?, ?, 1, ?, 0, NOW())";
                jdbcUtil.executeUpdate(sql, studentId, subject, isCorrect ? 1 : 0);
                log.info("为学生创建新的学习进度记录 - 学生ID: {}, 学科: {}", studentId, subject);
            } else {
                // 更新现有记录
                sql = "UPDATE student_learning_progress SET " +
                      "total_exercises = total_exercises + 1, " +
                      "correct_exercises = correct_exercises + ?, " +
                      "last_practice_time = NOW(), " +
                      "mastery_level = ((correct_exercises + ?) / (total_exercises + 1.0)) * 100 " +
                      "WHERE student_id = ? AND subject = ?";
                jdbcUtil.executeUpdate(sql, isCorrect ? 1 : 0, isCorrect ? 1 : 0, studentId, subject);
                log.info("更新学生现有学习进度记录 - 学生ID: {}, 学科: {}", studentId, subject);
            }
            
            // 如果指定了知识点且答错了，更新知识点分析表
            if (knowledgePoint != null && !knowledgePoint.isEmpty() && !isCorrect) {
                updateKnowledgePointAnalysis(studentId, knowledgePoint);
            }
            
            log.info("学习进度更新成功 - 学生ID: {}, 学科: {}", studentId, subject);
        } catch (Exception e) {
            log.error("更新学习进度失败: {}", e.getMessage(), e);
            // 实际项目应该抛出自定义异常
        }
    }
    
    /**
     * 更新知识点分析
     */
    private void updateKnowledgePointAnalysis(String studentId, String knowledgePoint) {
        try {
            String sql = "SELECT * FROM student_analysis WHERE student_id = ? AND topic = ?";
            List<Map<String, Object>> results = jdbcUtil.executeQuery(sql, studentId, knowledgePoint);
            
            if (results.isEmpty()) {
                // 创建新记录
                sql = "INSERT INTO student_analysis (student_id, topic, mistake_count, analysis_time) " +
                      "VALUES (?, ?, 1, NOW())";
                jdbcUtil.executeUpdate(sql, studentId, knowledgePoint);
            } else {
                // 更新现有记录
                sql = "UPDATE student_analysis SET mistake_count = mistake_count + 1, analysis_time = NOW() " +
                      "WHERE student_id = ? AND topic = ?";
                jdbcUtil.executeUpdate(sql, studentId, knowledgePoint);
            }
        } catch (Exception e) {
            log.error("更新知识点分析失败: {}", e.getMessage(), e);
        }
    }
} 